#!/usr/bin/python3
# -*- coding: utf-8 -*-

"""
# @version: v1.0
# @author : cd
# @Email : 19688513@qq.com
# @Project : new-horizons-engine
# @File : main.py
# @Software: PyCharm
# @time: 2025/6/5 10:46
# @description : 主函数运行
"""

import urllib3
import logging
import time
from datetime import date, timedelta
from apscheduler.schedulers.background import BackgroundScheduler

from AKShareDataFetcher import AKShareDataFetcher
from DatabaseManager import DatabaseManager
from Email.email_service import EmailService
from ExcelExporter import ExcelExporter
from StockBasicInfoManager import StockBasicInfoManager
from StockYearDataManager import StockYearDataManager
from TradeDateManager import TradeDateManager

# 配置日志
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

# 初始化调度器
scheduler = BackgroundScheduler()

email_service = EmailService()  # 将 email_service 提升为全局变量


def send_error_report(error_message, error_details):
    error_time = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())
    subject = f"系统错误报告 - {error_time}"

    # 发送错误报告
    error_sent = email_service.send_error_report(
        subject=subject,
        email_title="系统监控",
        error_message=error_message,
        error_details=error_details,
    )
    logging.info(f"错误报告发送{'成功' if error_sent else '失败'}")


def fetch_TradeDate():
    try:
        print("开始获取交易日期...")
        db_manager = DatabaseManager()
        trade_calendar = TradeDateManager(db_manager)
        data_fetcher = AKShareDataFetcher(max_retries=3, retry_delay=5, request_delay=1)

        trade_dates = data_fetcher.fetch_trade_dates(max_retries=3, retry_delay=3, request_delay=0.5)
        if not trade_dates.empty:
            trade_calendar.insert_trade_dates(trade_dates['trade_date'].tolist())
            logging.info("交易日期获取并存储成功")
        print("交易日期获取完成。")
    except Exception as e:
        logging.error(f"获取交易日期时发生错误: {e}")
        send_error_report(str(e), "fetch_TradeDate")


def fetch_StockBasicInfo():
    try:
        print("开始获取股票基本信息...")
        db_manager = DatabaseManager()
        stock_manager = StockBasicInfoManager(db_manager)
        stock_manager.initialize_stock_database()
        logging.info("股票基本信息初始化成功")
        print("股票基本信息初始化完成。")
    except Exception as e:
        logging.error(f"获取股票基本信息时发生错误: {e}")
        send_error_report(str(e), "fetch_StockBasicInfo")


def fetch_StockYearData():
    try:
        print("开始获取年度数据...")
        db_manager = DatabaseManager()
        trade_calendar = TradeDateManager(db_manager)
        exporter = ExcelExporter()
        data_manager = StockYearDataManager(db_manager)

        # 打印开始获取合并数据的消息
        print("开始获取合并数据...")
        data_manager.fetch_combined_data()
        # 打印完成获取合并数据的消息
        print("合并数据获取完成，休眠 1 分钟...")
        time.sleep(60)  # 休眠 1 分钟

        # 获取当前日期并减去一天
        test_date = date.today()  # 获取前一天的日期
        print(f"获取的日期: {test_date}")
        # 检查是否为交易日
        if not trade_calendar.is_tool_trading_day(test_date):
            print(f"{test_date} 不是交易日，跳过数据获取。")
            return
        target_date = test_date.strftime('%Y-%m-%d')
        signals = data_manager.fetch_and_generate_signals(target_date)

        # 使用 test_date 替代 target_date
        report_path = exporter.export_signals_report(signals, target_date)

        html_content = """
            <h1>每日推荐</h1>
            <p>
                signal_vol: 1: 成交量双均线条件：成交量接近5日均量且低于60日均量的70%<br>
                signal_price: 2: 价格均线多头排列：5日>10日>20日均线，且5日均线上扬<br>
                signal_vol_break: 3: 量能趋势突破：5日成交量均线上穿20日成交量均线<br>
                signal_trend: 4: 趋势延续验证：成交量均线多头排列(5>20>60)且价格高于3日均价<br>
                signal_volume_price: 5: 量价齐升：成交量放大10%以上，阳线且突破前日高点<br>
                signal_volatility: 6: 波动率适中：14日ATR处于近1年30%-70%分位之间<br>
                signal_rsi: 7: 价格RSI超卖：价格RSI低于其14日均值减1.5倍标准差<br>
                signal_vol_macd: 8: 成交量MACD金叉：成交量MACD上穿信号线<br>
                signal_vol_rsi: 9: 成交量RSI超卖：成交量RSI < 30<br>
                signal_vol_boll: 10: 成交量布林带收窄：带宽小于20日均宽的70%，且成交量在通道内<br>
                signal_vol_kdj: 11: 成交量KDJ金叉：K线上穿D线且J值>20<br>
                量价共振: 12: 量价齐升+成交量MACD金叉+价格RSI>50<br>
                底部反转信号: 13: 成交量RSI超卖+成交量KDJ金叉+价格RSI<40<br>
            </p>
        """

        recommendation_sent = email_service.send_daily_recommendation(
            html_content=html_content,
            email_title="每日推荐服务",
            subject="每日推荐",
            delay_seconds=5,  # 每组之间等待5秒
            attachment_path=report_path  # 附件路径
        )
        logging.info(f"每日推荐发送{'成功' if recommendation_sent else '部分失败'}")
        print("每日推荐发送完成。")
    except Exception as e:
        logging.error(f"获取年度数据或发送邮件时发生错误: {e}")
        send_error_report(str(e), "fetch_StockYearData")


# 每天早上 9:45 执行的任务
scheduler.add_job(fetch_TradeDate, 'cron', hour=21, minute=1, id='fetch_trade_date')
scheduler.add_job(fetch_StockBasicInfo, 'cron', hour=21, minute=30, id='fetch_stock_basic_info')
scheduler.add_job(fetch_StockYearData, 'cron', hour=15, minute=15, id='fetch_stock_year_data')

if __name__ == "__main__":
    print("启动任务调度器...")

    scheduler.start()

    try:
        while True:
            time.sleep(1)  # 使用 sleep 减少 CPU 占用
    except (KeyboardInterrupt, SystemExit):
        print("停止任务调度器...")
        scheduler.shutdown()
